package com.jrx.anytxn.param.job.paph.config;

import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.param.config.AnytxnBatchProperties;
import com.jrx.anytxn.param.config.PaphConfig;
import com.jrx.anytxn.param.constant.Constant;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.entity.TlFilePaymentLog;
import com.jrx.anytxn.param.job.paph.bean.PrepayFileBean;
import com.jrx.anytxn.param.job.paph.step.ReadPrepayFileListener;
import com.jrx.anytxn.param.job.paph.step.ReadPrepayFileProcessor;
import com.jrx.anytxn.param.job.paph.step.ReadPrepayFileWriter;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.EnableBatchProcessing;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.MultiResourceItemReader;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.mapping.FieldSetMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.batch.item.file.transform.FieldSet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.validation.BindException;

import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * @author liuyu
 * @Description 读取提前还款文件批量
 */
@Configuration
@EnableConfigurationProperties(AnytxnBatchProperties.class)
@EnableBatchProcessing
public class ReadPrepayFileConfiguration {

	private static final Logger logger = LoggerFactory.getLogger(ReadPrepayFileConfiguration.class);

	@Autowired
	private JobBuilderFactory jobBuilderFactory;
	@Autowired
	private StepBuilderFactory stepBuilderFactory;
	@Autowired
	private IOrganizationTableService organizationTableService;
	@Autowired
	private AnytxnBatchProperties anytxnBatchProperties;
	@Autowired
	private ReadPrepayFileProcessor readPrepayFileProcessor;
	@Autowired
	private ReadPrepayFileWriter readPrepayFileWriter;
	@Autowired
	private PaphConfig paphConfig;
	@Autowired
	private ReadPrepayFileListener readPrepayFileListener;

	@Bean
	public Job readPrepayFileJob() {
		return jobBuilderFactory.get("readPrepayFileJob")
				.listener(readPrepayFileListener)
				.start(readPrepayFileStep())
				.build();
	}

	@Bean
	public Step readPrepayFileStep() {
		return stepBuilderFactory.get("readPrepayFileStep")
				.<PrepayFileBean, TlFilePaymentLog>chunk(anytxnBatchProperties.getReadPrepayFileConfig().getChunkLimit())
				.reader(prepayMultiFileReader())
				.processor(readPrepayFileProcessor)
				.writer(readPrepayFileWriter)
				.taskExecutor(new SimpleAsyncTaskExecutor())
				.throttleLimit(anytxnBatchProperties.getReadPrepayFileConfig().getThrottleLimit())
				.build();
	}

	@Bean
	@StepScope
	public MultiResourceItemReader<PrepayFileBean> prepayMultiFileReader() {
        PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(Constant.DEFAULT_ORG_NUMBER);
        String toDay = DateUtils.format(org.getNextProcessingDate(), "yyyyMMdd");
        // 经营贷路径
		String jyFilePath =
				paphConfig.getRepayPreResultFilePath() + org.getTenantId() + File.separator + toDay + File.separator + Constant.PRODECUT_TYPE_JY + File.separator;
		// 消费贷路径
		String xfFilePath =
				paphConfig.getRepayPreResultFilePath() + org.getTenantId() + File.separator + toDay + File.separator + Constant.PRODECUT_TYPE_XF + File.separator;
		String businessCode = Constant.PREPAY_RESULT;
		String jyFileName = jyFilePath  + Constant.LS_BANK +
						Constant.PRODECUT_TYPE_JY + toDay + businessCode + ".txt";
		String xfFileName = xfFilePath + Constant.LS_BANK + Constant.PRODECUT_TYPE_XF + toDay + businessCode + ".txt";
		MultiResourceItemReader<PrepayFileBean> reader = new MultiResourceItemReader<>();
		Path jyPath = Paths.get(jyFileName);
		Path xfPath = Paths.get(xfFileName);
		Resource[] resources = new Resource[2];
		if (Files.exists(jyPath)) {
			resources[0] = new FileSystemResource(jyPath);
		} else {
			logger.error("经营贷文件不存在！{}", jyFileName);
		}
		if (Files.exists(xfPath)) {
			resources[1] = new FileSystemResource(xfPath);
		} else {
			logger.error("消费贷文件不存在{}", xfFileName);
		}
		reader.setResources(resources);
		reader.setDelegate(readPrepayFileReader());
		return reader;
	}


	@Bean
	@StepScope
	public FlatFileItemReader<PrepayFileBean> readPrepayFileReader() {
		FlatFileItemReader<PrepayFileBean> fileItemReader = new FlatFileItemReader<>();

		// 获取指定目录文件
		DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer();
		tokenizer.setNames("line", "loanNo", "tradeDate", "tradeAmt", "tradeSeqNo", "tradeType", "acctFlag");
		tokenizer.setDelimiter("|");
		// 跳过1、3行
		fileItemReader.setComments(new String[]{"H|", "F|"});
		DefaultLineMapper<PrepayFileBean> mapper = new DefaultLineMapper<>();
		mapper.setLineTokenizer(tokenizer);
		FieldSetMapper<PrepayFileBean> fieldSetMapper = new FieldSetMapper<PrepayFileBean>() {
			@Override
			public PrepayFileBean mapFieldSet(FieldSet fieldSet) throws BindException {
				PrepayFileBean bean = new PrepayFileBean();
				bean.setLoanNo(fieldSet.readString("loanNo"));
				bean.setTradeDate(fieldSet.readString("tradeDate"));
				bean.setTradeAmt(fieldSet.readBigDecimal("tradeAmt"));
				bean.setTradeSeqNo(fieldSet.readString("tradeSeqNo"));
				bean.setTradeType(fieldSet.readString("tradeType"));
				bean.setAcctFlag(fieldSet.readString("acctFlag"));
				return bean;
			}
		};
		mapper.setFieldSetMapper(fieldSetMapper);
		mapper.afterPropertiesSet();
		fileItemReader.setLineMapper(mapper);
		return fileItemReader;
	}

}
